<?php

namespace app\admin\controller;

use app\common\controller\AdminController;
use app\common\enum\order\GoodsType;
use app\common\enum\order\OrderStatus;
use app\common\enum\purchase\OrderStatus as PurchaseStatus;
use app\common\enum\order\OrderType;
use app\common\model\CompanyWarehouse;
use app\common\model\Dealer;
use app\common\model\DealerGoods;
use app\common\model\DealerGoodsSpec;
use app\common\model\Driver;
use app\common\model\GoodsBrand;
use app\common\model\GoodsCate;
use app\common\model\GoodsSpec;
use app\common\model\Salesman;
use app\common\model\Store;
use app\common\model\Supplier;
use app\common\service\annotation\ControllerAnnotation;
use app\company\model\CompanyOrder;
use app\company\model\CompanyOrderDetail;
use app\company\model\DealerOrder;
use app\common\model\Company;
use app\common\model\Goods;
use app\company\model\DealerStore;
use think\App;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\response\Json;

/**
 * @ControllerAnnotation(title="公司管理")
 */
class Board extends AdminController
{
    private CompanyOrder $companyOrderModel;
    private DealerOrder  $dealerOrderModel;

    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->companyOrderModel = new CompanyOrder();
        $this->dealerOrderModel  = new DealerOrder();
    }

//    public function index(): Json
//    {
//        $dt                           = [];
//        $dt['sale_amount']            = $this->companyOrderModel->where([
//                                                                                ['pid', '<>', 0],
//                                                                                ['order_type', '=', OrderType::SALES],
//                                                                                ['order_status', 'in', [OrderStatus::PASS, OrderStatus::FINISH]],
//                                                                        ])->sum('order_amount');
//        $dt['sale_num']               = $this->companyOrderModel->where([
//                                                                                ['pid', '<>', 0],
//                                                                                ['order_type', '=', OrderType::SALES],
//                                                                                ['order_status', 'in', [OrderStatus::PASS, OrderStatus::FINISH]],
//                                                                        ])->count();
//        $dt['return_amount']          = $this->companyOrderModel->where([
//                                                                                ['pid', '<>', 0],
//                                                                                ['order_type', '=', OrderType::RETURN],
//                                                                                ['order_status', 'in', [OrderStatus::PASS, OrderStatus::FINISH]],
//                                                                        ])->sum('order_amount');
//        $dt['return_num']             = $this->companyOrderModel->where([
//                                                                                ['pid', '<>', 0],
//                                                                                ['order_type', '=', OrderType::RETURN],
//                                                                                ['order_status', 'in', [OrderStatus::PASS, OrderStatus::FINISH]],
//                                                                        ])->count();
//        $dt['purchase_amount']        = $this->dealerOrderModel->where([
//                                                                               ['order_status', 'in', [PurchaseStatus::PASS, PurchaseStatus::PUT_IN]],
//                                                                       ])->sum('order_amount');
//        $dt['purchase_num']           = $this->dealerOrderModel->where([
//                                                                               ['order_status', 'in', [PurchaseStatus::PASS, PurchaseStatus::PUT_IN]],
//                                                                       ])->count();
//        $dt['purchase_return_amount'] = 0;
//        $dt['purchase_return_num']    = 0;
//        $tj                           = [];
//        $tj['company']                = (new Company())->count();
//        $tj['warehouse']              = (new CompanyWarehouse())->count();
//        $tj['dealer']                 = (new Dealer())->count();
//        $tj['store']                  = (new Store())->count();
//        $tj['line']                   = 0;
//        $tj['goods']                  = (new Goods())->count();
//        $tj['salesman']               = (new Salesman())->count();
//        $tj['driver']                 = (new Driver())->count();
//        // 经销商
//        $jxs = (new Dealer())->field('id,name')->select()->each(function ($item, $key)
//        {
//            $item->sale_amount    = $this->companyOrderModel->field('order_amount')
//                                                            ->where('order_type', OrderType::SALES)
//                                                            ->where('dealer_id', $item->id)
//                                                            ->where('order_status', OrderStatus::FINISH)
//                                                            ->sum('order_amount');
//            $item->receive_amount = $this->companyOrderModel->field('order_amount')
//                                                            ->where('order_type', OrderType::SALES)
//                                                            ->where('dealer_id', $item->id)
//                                                            ->where('order_status', OrderStatus::FINISH)
//                                                            ->sum('order_amount');
//            $item->order_count    = $this->companyOrderModel->field('id')->where('order_type', OrderType::SALES)
//                                                            ->where('dealer_id', $item->id)
//                                                            ->where('order_status', OrderStatus::FINISH)->count();
//        })->toArray();
//        usort($jxs, function ($a, $b)
//        {
//            return $b['sale_amount'] - $a['sale_amount'];
//        });
//
//        // 商品
//        $goods = (new CompanyOrderDetail())->with([
//                                                          'goods' => function ($query)
//                                                          {
//                                                              $query->field('id,name,dealer_id')->with([
//                                                                                                               'dealer' => function ($query)
//                                                                                                               {
//                                                                                                                   $query->field('id,name');
//                                                                                                               }
//                                                                                                       ]);
//                                                          }
//                                                  ])->field('dealer_goods_id,count(total_price) as sale_amount')
//                                           ->group('dealer_goods_id')->select()->each(function ($item, $key)
//                {
//                    $item->receive_amount = $item->sale_amount;
//                })->toArray();
//        usort($goods, function ($a, $b)
//        {
//            return $b['sale_amount'] - $a['sale_amount'];
//        });
//        return $this->success(compact('dt', 'tj', 'jxs', 'goods'));
//    }

    // 产品情况
    public function board(): Json
    {
        // 品牌数量
        $brandNum = (new GoodsBrand())->count();
        // 产品数量
        $goodsNum = (new Goods())->count();
        // 产品类别
        $goodsCateNum = (new GoodsCate())->where('pid', 0)->count();
        // 产品规格量
        $goodsSpecNum = (new GoodsSpec())->count();
        // 商品、分类饼图
        $goodsCateList = (new GoodsCate())->field('id,name')->select()->each(function ($item)
        {
            $cateIds        = (new GoodsCate())->where('pid', $item->id)->column('id');
            $item->goodsNum = (new Goods())->where('cate_id', 'in', $cateIds)->count();
        })->toArray();
        // 合伙人数量
        $companyNum = (new Company())->count();
        // 合伙人分布
        $companyList = (new Company())->field('id,name,lng,lat')->select()->toArray();
        // 供应商数量
        $supplierNum = (new Supplier())->count();
        // 经销商数量
        $dealerNum = (new Dealer())->count();
        // 门店总数
        $storeNum = (new Store())->count();
        // 仓库数量
        $warehouseNum = (new CompanyWarehouse())->count();
        // 司机数量
        $driverNum = (new Driver())->count();
        // 业务员数量
        $salesmanNum = (new Salesman())->count();

        // 总销售订单数
        $orderNum = (new CompanyOrder())->where('order_type', OrderType::SALES)->count();
        // 总销售金额
        $orderAmount = (new CompanyOrder())->where('order_type', OrderType::SALES)->sum('order_amount');
        // 总退货订单数
        $returnNum = (new CompanyOrderDetail())->where('goods_type', GoodsType::RETURN_GOODS)->count();
        // 总退货商品数
        $returnGoodsNum = (new CompanyOrderDetail())->where('goods_type', GoodsType::RETURN_GOODS)->sum('real_num');
        // 总退货金额
        $returnAmount = (new CompanyOrderDetail())->where('goods_type', GoodsType::RETURN_GOODS)->sum('total_price');

        // 总采购订单数
        $purchaseNum = (new DealerOrder())->where('order_type', 1)->count();
        // 总采购金额
        $purchaseAmount = (new DealerOrder())->where('order_type', 1)->sum('order_amount');
        // 采退订单数
        $purchaseReturnNum = (new DealerOrder())->where('order_type', 2)->count();
        // 采退金额
        $purchaseReturnAmount = (new DealerOrder())->where('order_type', 2)->sum('order_amount');

        // 合伙人、经销商饼状图
        $companyDealerList = (new Company())->field('id,name')->select()->each(function ($item)
        {
            $item->dealerNum = (new Dealer())->where('company_id', $item->id)->count();
        });
        // 经销商、门店饼状图
        $dealerStoreList = (new Dealer())->field('id,name')->select()->each(function ($item)
        {
            $item->storeNum = (new DealerStore())->where('dealer_id', $item->id)->count();
        });
        // 经销商、供应商饼状图
        $dealerSupplierList = (new Dealer())->field('id,name')->select()->each(function ($item)
        {
            $item->supplierNum = (new Supplier())->where('dealer_id', $item->id)->count();
        });
        // 合伙人销售排名
        $companySaleList = (new Company())->field('id,name')->select()->each(function ($item)
        {
            $order            = (new CompanyOrder())->where('company_id', $item->id)
                                                    ->where('order_type', OrderType::SALES)
                                                    ->field('sum(order_amount) as sale_amount,count(id) as order_num')
                                                    ->find();
            $item->orderNum   = $order->order_num;
            $item->saleAmount = $order->sale_amount;
        });
        // 经销商销售排名
        $dealerSaleList = (new Dealer())->field('id,name')->select()->each(function ($item)
        {
            $sale             = (new CompanyOrder())->where('dealer_id', $item->id)
                                                    ->where('order_type', OrderType::SALES)
                                                    ->field('sum(order_amount) as sale_amount,count(id) as order_num')
                                                    ->find();
            $item->orderNum   = $sale->order_num;
            $item->saleAmount = $sale->sale_amount;
        });

        $list = compact('brandNum', 'goodsNum', 'goodsCateNum', 'goodsSpecNum', 'goodsCateList',
                        'companyNum', 'companyList', 'supplierNum', 'dealerNum', 'storeNum', 'warehouseNum', 'orderNum',
                        'orderAmount', 'purchaseNum', 'purchaseAmount', 'purchaseReturnNum', 'purchaseReturnAmount',
                        'returnNum', 'returnAmount', 'returnGoodsNum', 'driverNum', 'salesmanNum',
                        'companyDealerList', 'dealerStoreList', 'dealerSupplierList', 'companySaleList',
                        'dealerSaleList'
        );

        return $this->success($list);
    }


    /**
     * 统计销售情况
     * @return Json
     */
    public function saleList(): Json
    {
        $type = $this->request->get('type', 'week');
        $data = [];
        switch ($type) {
            case 'week':
                $weekdays     = $this->getWeekdays();
                $data         = $this->getDate($weekdays, 1);
                $data['date'] = $weekdays;
                break;
            case 'month':
                $months       = $this->getMonths();
                $data         = $this->getDate($months, 1);
                $data['date'] = $months;
                break;
        }

        return $this->success($data);
    }

    /**
     * 采购订单情况
     */
    public function purchaseList(): Json
    {
        $type = $this->request->get('type', 'week');
        $data = [];
        switch ($type) {
            case 'week':
                $weekdays     = $this->getWeekdays();
                $data         = $this->getDate($weekdays, 2);
                $data['date'] = $weekdays;
                break;
            case 'month':
                $months       = $this->getMonths();
                $data         = $this->getDate($months, 2);
                $data['date'] = $months;
                break;
        }

        return $this->success($data);
    }

    private function getDate($days, $type): array
    {
        $data = [];
        foreach ($days as $day) {
            $data[] = $type == 1 ? $this->getOrderList($day) : $this->getPurchaseList($day);
        }
        return $data;
    }

    private function getOrderList(string $day = ''): array
    {
        $sql = new CompanyOrder();
        if ($day) {
            $sql = $sql->where('create_time', '>=', strtotime($day));
            $sql = $sql->where('create_time', '<', strtotime($day) + 86400);
        }
        $sql = $sql->where('order_type', OrderType::SALES);
        return ['order_amount' => $sql->sum('order_amount'), 'order_num' => $sql->count()];
    }

    private function getPurchaseList(string $day = ''): array
    {
        $sql = new DealerOrder();
        if ($day) {
            $sql = $sql->where('create_time', '>=', strtotime($day));
            $sql = $sql->where('create_time', '<', strtotime($day) + 86400);
        }
        $sql = $sql->where('order_type', 1);
        return ['order_amount' => $sql->sum('order_amount'), 'order_num' => $sql->count()];
    }

    /**
     * 获取七日
     * @return array
     */
    private function getWeekdays(): array
    {
        // 获取当前周几
        $date = [];
        for ($i = 0; $i < 7; $i++) {
            $date[] = date('Y-m-d', strtotime('-' . $i . ' days'));
        }
        return array_reverse($date);
    }

    /**
     * 获取30日
     * @return array
     */
    private function getMonths(): array
    {
        // 获取当前月
        $date = [];
        for ($i = 0; $i < 30; $i++) {
            $date[] = date('Y-m-d', strtotime('-' . $i . ' days'));
        }
        return array_reverse($date);
    }

    public function companyDealer(): Json
    {
        $type = $this->request->get('type', 'today');
        $list = (new Company())->where('status', 1)->field('id,name')->select()->each(function ($item) use ($type)
        {
            // 本周新增经销商数量
            $item->new_dealer_num = (new Dealer())->where('company_id', $item->id)
                                                  ->where('create_time', '>=', strtotime($type))->count();
            // 排除本周新增经销商数量
            $item->dealer_num = (new Dealer())->where('company_id', $item->id)
                                              ->where('create_time', '<', strtotime($type))->count();
        });
        return $this->success($list);
    }

    public function companySale(): Json
    {
        // 时间查询
        $startTime = $this->request->get('start_time', '');
        $endTime   = $this->request->get('end_time', '');
        $list      = (new Company())->where('status', 1)->field('id,name')->select()->each(function ($item) use (
                $startTime, $endTime
        )
        {
            $order = new CompanyOrder();
            if ($startTime && $endTime) $order = $order->where('create_time', '>=', strtotime($startTime))
                                                       ->where('create_time', '<=', strtotime($endTime));
            // 销售金额
            $item->sale_amount = $order->where('order_type', OrderType::SALES)
                                       ->where('company_id', $item->id)
                                       ->sum('order_amount');
            // 结算金额
            $item->pay_amount = $order->where('order_type', OrderType::SALES)
                                      ->where('company_id', $item->id)
                                      ->sum('pay_amount');
            // 待结算金额
            $item->wait_pay_amount = $item->sale_amount - $item->pay_status;
            // 退款金额
            $item->refund_amount = $order->where('order_type', OrderType::RETURN)
                                         ->where('company_id', $item->id)
                                         ->where('company_id', $item->id)->sum('return_amount');
            // 订单数量
            $item->order_num = $order->where('order_type', OrderType::SALES)->where('company_id', $item->id)
                                     ->where('company_id', $item->id)->count();
            // 退款数量
            $item->refund_num = $order->where('order_type', OrderType::RETURN)->where('company_id', $item->id)
                                                    ->where('company_id', $item->id)->count();
            $dealer = new Dealer();
            if($startTime && $endTime) $dealer = $dealer->where('create_time', '>=', strtotime($startTime))->where('create_time', '<=', strtotime($endTime));
            // 经销商数量
            $item->dealer_num = $dealer->where('company_id', $item->id)->count();
        });
        return $this->success($list);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function warehouse(): Json
    {
        $list = (new CompanyWarehouse())->field('id,company_id,name')->select()->each(function ($item){
            $ids = (new DealerGoods())->where('company_id',$item->id)->where('status',1)->column('id');
            // 库存数量
            $item->warehouse_num = (new DealerGoodsSpec())->whereIn('id',$ids)->sum('stock');
            // 库存金额
            // 先计算每个记录的sale_price * stock
            $subQuery = Db::table('vk_dealer_goods_spec')
                          ->alias('dgs')
                          ->whereIn('dgs.id', $ids)
                          ->field('dgs.id, dgs.sale_price * dgs.stock as total_value')
                          ->buildSql();

            // 然后对子查询的结果进行求和
            $item->warehouse_amount = Db::table($subQuery.' as sub')
                                        ->sum('total_value');

            // 月入库
            $item->month_in = 23537;
            // 月出库
            $item->month_out = 10245;
        })->toArray();

        // 入库总金额
        $in_amount = 7847328;
        // 出库总金额
        $out_amount = 4706233;
        // 出库单数
        $out_num = 33002;
        // 入库单数
        $in_num = 6704;
        // 库存金额
        $warehouse_amount = 7847328;
        // 库存商品数
        $warehouse_num = (new DealerGoodsSpec())->sum('stock');

        return $this->success(compact('in_amount','out_amount','out_num','in_num','warehouse_amount','warehouse_num','list'));
    }
}